using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using TerritoryGame.Application.Dtos;
using TerritoryGame.Application.Interfaces;
using TerritoryGame.Application.Commands;
using TerritoryGame.Domain.Interfaces;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;

namespace TerritoryGame.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize] // 恢复JWT认证
public class UsersController : ControllerBase
{
    private readonly IAppUserService _userService;
    private readonly IAppAvatarService _avatarService;
    private readonly IDomainEventPublisher _eventPublisher;

    public UsersController(
        IAppUserService userService,
        IAppAvatarService avatarService,
        IDomainEventPublisher eventPublisher)
    {
        _userService = userService;
        _avatarService = avatarService;
        _eventPublisher = eventPublisher;
    }

    

    /// <summary>
    /// 获取头像文件（静态路由，放在参数路由之前）
    /// </summary>
    [HttpGet("avatar-file/{fileName}")]
    [AllowAnonymous] // 头像文件可以匿名访问
    public async Task<IActionResult> GetAvatarFile(string fileName)
    {
        var (fileBytes, contentType, actualFileName) = await _avatarService.GetAvatarFileAsync(fileName);
        return File(fileBytes, contentType, actualFileName);
    }

    /// <summary>
    /// 获取用户详情
    /// </summary>
    [HttpGet("{userId:guid}")]
    public async Task<IActionResult> GetUser(Guid userId)
    {
        var result = await _userService.GetUserByIdAsync(userId);
        return Ok(result);
    }



    /// <summary>
    /// 获取用户头像信息
    /// </summary>
    [HttpGet("{userId:guid}/avatar-info")]
    public async Task<IActionResult> GetUserAvatarInfo(Guid userId)
    {
        var result = await _avatarService.GetUserAvatarInfoAsync(userId);
        return Ok(result);
    }

    

    /// <summary>
    /// 更新用户
    /// </summary>
    [HttpPut("{userId:guid}")]
    public async Task<IActionResult> UpdateUser(Guid userId, [FromBody] UpdateUserDto dto)
    {
        var result = await _userService.UpdateUserAsync(userId, dto);
        return Ok(result);
    }

    /// <summary>
    /// 删除用户
    /// </summary>
    [HttpDelete("{userId:guid}")]
    public async Task<IActionResult> DeleteUser(Guid userId)
    {
        var currentUserId = GetCurrentUserId();
        var result = await _userService.DeleteUserAsync(userId, currentUserId);
        return Ok(result);
    }

    /// <summary>
    /// 修改密码
    /// </summary>
    [HttpPost("{userId:guid}/change-password")]
    public async Task<IActionResult> ChangePassword(Guid userId, [FromBody] ChangePasswordDto dto)
    {
        try
        {
            Console.WriteLine($"收到修改密码请求 - UserId: {userId}");
            var currentUserId = GetCurrentUserId();
            
            // 手动验证密码一致性，避免 [Compare] 属性的问题
            if (dto.NewPassword != dto.ConfirmPassword)
            {
                var errors = new Dictionary<string, string[]>
                {
                    ["ConfirmPassword"] = new[] { "两次输入的密码不一致" }
                };
                
                var api = ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "参数验证失败", new { errors });
                return StatusCode(api.Code, api);
            }
            
            if (!ModelState.IsValid)
            {
                var errors = ModelState.Where(kv => kv.Value?.Errors.Count > 0)
                    .ToDictionary(
                        kv => kv.Key,
                        kv => kv.Value!.Errors.Select(e => e.ErrorMessage).ToArray());

                var api = ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "参数验证失败", new { errors });
                return StatusCode(api.Code, api);
            }

            var result = await _userService.ChangePasswordAsync(userId, dto, currentUserId);

            // 将服务层返回码映射为HTTP状态码
            if (result.Code == (int)ApiStatusCode.SUCCESS)
            {
                return Ok(result);
            }
            return StatusCode(result.Code, result);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"修改密码控制器异常: {ex.Message}");
            var api = ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, ex.Message);
            return StatusCode(api.Code, api);
        }
    }

    /// <summary>
    /// 启用用户
    /// </summary>
    [HttpPost("{userId:guid}/enable")]
    public async Task<IActionResult> EnableUser(Guid userId)
    {
        var currentUserId = GetCurrentUserId();
        var result = await _userService.EnableUserAsync(userId, currentUserId);
        return Ok(result);
    }

    /// <summary>
    /// 禁用用户
    /// </summary>
    [HttpPost("{userId:guid}/disable")]
    public async Task<IActionResult> DisableUser(Guid userId)
    {
        var currentUserId = GetCurrentUserId();
        var result = await _userService.DisableUserAsync(userId, currentUserId);
        return Ok(result);
    }



    /// <summary>
    /// 上传用户头像
    /// </summary>
    [HttpPost("{userId:guid}/avatar")]
    [Consumes("multipart/form-data")]
    public async Task<IActionResult> UploadUserAvatar(Guid userId)
    {
        var currentUserId = GetCurrentUserId();
        var form = await Request.ReadFormAsync();
        var selectedFile = form.Files.FirstOrDefault();
        if (selectedFile == null || selectedFile.Length == 0)
        {
            var api = ApiResult.Failed((int)ApiStatusCode.BAD_REQUEST, "文件不能为空，请以 multipart/form-data 提交，字段名任意（file/avatar均可）");
            return StatusCode(api.Code, api);
        }

        var result = await _avatarService.UploadUserAvatarAsync(userId, selectedFile, currentUserId);
        if (result == null)
        {
            var apiNull = ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, "服务返回空结果");
            return StatusCode(apiNull.Code, apiNull);
        }
        
        // 按服务返回的业务码映射HTTP状态码，确保错误有明确提示
        if (result.Code == 200)
        {
            return Ok(result);
        }
        
        return StatusCode(result.Code, result);
    }



    /// <summary>
    /// 获取当前用户ID
    /// </summary>
    private Guid GetCurrentUserId()
    {
        var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier);
        if (userIdClaim != null && Guid.TryParse(userIdClaim.Value, out var userId))
        {
            return userId;
        }
        return Guid.Empty;
    }
} 